/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package me.zhengjie.modules.other.rest;

import cn.hutool.core.util.XmlUtil;
import com.alibaba.fastjson.JSONObject;
import com.qiaofang.applet.common.exception.BusinessException;
import com.qiaofang.applet.common.util.RedisKeyUtil;
import com.qiaofang.applet.common.util.RedisUtil;
import com.qiaofang.applet.service.member.service.WxFollowUsersService;
import com.qiaofang.applet.service.other.domain.CityCompany;
import com.qiaofang.applet.service.other.domain.Corporation;
import com.qiaofang.applet.service.other.domain.SwitchConfig;
import com.qiaofang.applet.service.other.service.CityCompanyService;
import com.qiaofang.applet.service.other.service.CorporationService;
import com.qiaofang.applet.service.other.service.dto.CityCompanyDto;
import com.qiaofang.applet.service.property.service.SyncDataLogService;
import com.qiaofang.applet.service.property.service.dto.SyncDataLogQueryDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.annotation.AnonymousAccess;
import me.zhengjie.modules.quartz.service.dto.SyncCommon;
import me.zhengjie.modules.quartz.task.V20EstateRockIdBrushTask;
import me.zhengjie.modules.quartz.task.onlyOnce.PropertyPhotoFixTask;
import me.zhengjie.modules.quartz.utils.AesException;
import me.zhengjie.modules.quartz.utils.WXPublicUtils;
import me.zhengjie.modules.sync.DataErrorPullService;
import me.zhengjie.modules.sync.processing.SignSyncProcessing;
import me.zhengjie.modules.sync.pull.SignSync;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.persistence.Id;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author QF2019
 * @website https://el-admin.vip
 * @date 2020-09-20
 **/
@RestController
@RequiredArgsConstructor
@Api(tags = "小程序：同步日志")
@RequestMapping("/api/syncData")
@Slf4j
public class SyncDataController {

    @Autowired
    private SyncDataLogService syncDataLogService;

    @Autowired
    DataErrorPullService dataErrorPullService;

    //集团
    @Autowired
    private CorporationService corporationService;
    //城市公司
    @Autowired
    private CityCompanyService cityCompanyService;

    @Autowired
    private SignSync signSync;

    @Autowired
    private SignSyncProcessing signSyncProcessing;

    @Autowired
    private V20EstateRockIdBrushTask v20EstateRockIdBrushTask;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private PropertyPhotoFixTask propertyPhotoFixTask;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private WxFollowUsersService wxFollowUsersService;

    @GetMapping
    @ApiOperation("查询SyncData")
    public ResponseEntity<Object> query(SyncDataLogQueryDto criteria, Pageable pageable) {
        return new ResponseEntity<>(syncDataLogService.findByParams(criteria, pageable), HttpStatus.OK);
    }

    @PostMapping("/retry")
    @ApiOperation("重新同步数据")
    public ResponseEntity<Object> retry(@RequestBody List<String> ids) {
        boolean isOk = false;
        if (!CollectionUtils.isEmpty(ids)) {
            isOk = dataErrorPullService.pullSyncDataErrorLogById(ids.get(0));
        }
        return new ResponseEntity<>(isOk, HttpStatus.OK);
    }


    @PostMapping("/getAllSignData")
    @ApiOperation(value = "刷新电子合同数据", notes = "刷新电子合同数据")
    @AnonymousAccess
    public ResponseEntity<Object> getAllSignData() {
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("deleted", match -> match.exact())
                .withIgnoreNullValues();
        Corporation corporation = new Corporation();
        corporation.setDeleted(Boolean.FALSE);
        Iterable<Corporation> list = corporationService.findAll(Example.of(corporation, matcher));
        list.forEach(item -> {
            SwitchConfig switchConfig = item.getSwitchConfig();
            if (switchConfig == null || switchConfig.getEDeals() == null || "关闭".equals(switchConfig.getEDeals())) {
                return;
            }
            List<CityCompanyDto> cityCompanyDtoList = cityCompanyService.getCompanyList(item.getCorporationCode());
            if (null == cityCompanyDtoList) {
                return;
            }
            cityCompanyDtoList.stream().forEach(cityCompanyDto -> {
                if (cityCompanyDto.getStatus() == 1) {
                    try {
                        SyncCommon syncCommon = new SyncCommon();
                        syncCommon.setCorporationCode(item.getCorporationCode());
                        syncCommon.setAppId(item.getPullAppId());
                        syncCommon.setAppKey(item.getPullAppKey());
                        syncCommon.setDomain(item.getPullDomain());
                        //具体公司信息
                        syncCommon.setCityCode(cityCompanyDto.getCityCode());
                        syncCommon.setCompanyUuid(cityCompanyDto.getCompanyUuid());
                        //是否初始化
                        syncCommon.setInit(true);
                        signSync.pull(syncCommon, null);
                    } catch (Exception e) {
                        log.error("signSync error {}", e);
                    }
                }
            });
        });
        //电子合同
        try {
            signSyncProcessing.run();
        } catch (Exception e) {
            log.error("signSyncProcessing error", e);
        }
        return ResponseEntity.ok(HttpStatus.OK);
    }

    @PostMapping("/getAllData")
    @ApiOperation(value = "全量刷历史数据", notes = "全量刷历史数据")
    @AnonymousAccess
    public ResponseEntity<Object> getAllData() {
        v20EstateRockIdBrushTask.run();
        return ResponseEntity.ok(HttpStatus.OK);
    }

    @PostMapping("/deleteAllDictCache")
    @ApiOperation(value = "清除所有集团字典缓存", notes = "清除所有集团字典缓存")
    @AnonymousAccess
    public ResponseEntity<Object> deleteAllDictCache() {

        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("deleted", match -> match.exact())
                .withIgnoreNullValues();
        Corporation corporation = new Corporation();
        corporation.setDeleted(Boolean.FALSE);
        Iterable<Corporation> list = corporationService.findAll(Example.of(corporation, matcher));
        list.forEach(item -> {
            redisUtil.del(RedisKeyUtil.getDictCacheKey(item.getCorporationCode()));
                });
        return ResponseEntity.ok(HttpStatus.OK);
    }

    @PostMapping("/updatePropertyPhoto")
    @ApiOperation(value = "更新历史房源图片顺序", notes = "更新历史房源图片顺序")
    @AnonymousAccess
    public ResponseEntity<Object> updatePropertyPhoto(@RequestParam("companyUuid") String companyUuid, @RequestParam("corporationCode") String corporationCode) {
        propertyPhotoFixTask.fixPropertyPhoto(companyUuid, corporationCode);
        return ResponseEntity.ok(HttpStatus.OK);
    }

    @PostMapping("/deleteAllWaterMarkCache")
    @ApiOperation(value = "删除所有房源水印缓存", notes = "删除所有房源水印缓存")
    @AnonymousAccess
    public ResponseEntity<Object> deleteAllWaterMarkCache(@RequestParam(value = "corporationCode", required = false) String corporationCode) {
        if (StringUtils.equals("deleteAllWaterMarkCache", corporationCode)) {
            Query query = new Query(Criteria.where("status").is(1));
            List<CityCompany> cityCompanyList = mongoTemplate.find(query, CityCompany.class);
            if (!CollectionUtils.isEmpty(cityCompanyList)) {
                cityCompanyList.forEach(cityCompany -> {
                    if (redisUtil.hasKey(RedisKeyUtil.getPropertyWaterMarkKey(cityCompany.getCompanyUuid()))) {
                        redisUtil.del(RedisKeyUtil.getPropertyWaterMarkKey(cityCompany.getCompanyUuid()));
                    }
                });
            }
        }
        return ResponseEntity.ok(HttpStatus.OK);
    }

    @PostMapping("/getUserPushEvents")
    @ApiOperation(value = "微信关注监听事件", notes = "微信关注监听事件")
    @AnonymousAccess
    public ResponseEntity<Object> getUserPushEvents(@RequestParam(value = "corporationCode", required = false) String corporationCode
            , HttpServletRequest httpServletRequest) {
        Map<String, Object> stringObjectMap = null;
        try {
            int len = httpServletRequest.getContentLength();
            System.out.println("数据流长度:" + len);
            //获取HTTP请求的输入流
            InputStream is = httpServletRequest.getInputStream();
            //已HTTP请求输入流建立一个BufferedReader对象
            BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            //读取HTTP请求内容
            String buffer;
            StringBuffer sb = new StringBuffer();
            while ((buffer = br.readLine()) != null) {
                //在页面中显示读取到的请求参数
                sb.append(buffer);
            }
            stringObjectMap = XmlUtil.xmlToMap(sb.toString());
        } catch (UnsupportedEncodingException ex) {
            log.error("UnsupportedEncodingException error:{}", ex);
        } catch (IOException ex) {
            log.error("IOException error:{}", ex);
        }
        log.info("stringObjectMap:{}", JSONObject.toJSONString(stringObjectMap));
        return ResponseEntity.ok(HttpStatus.OK);
    }

    @RequestMapping("/wxpublic/verify_wx_token")
    @AnonymousAccess
    public String verifyWXToken(@RequestParam(value = "corporationCode", required = false) String corporationCode,
                                HttpServletRequest request) throws AesException {
        //关注事件
        wxFollowUsersService.monitorWxFollowEvent(corporationCode, request);
        //响应微信公众号
        String msgSignature = request.getParameter("signature");
        String msgTimestamp = request.getParameter("timestamp");
        String msgNonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        if (WXPublicUtils.verifyUrl(msgSignature, msgTimestamp, msgNonce)) {
            return echostr;
        }
        return null;
    }

}